#include <sys_config.h>

#ifdef HILINK_SUPPORT
#include <basic_types.h>
#include <mediatypes.h>
#include <osal/osal.h>
#include <os/tds2/itron.h>
#include <osal/osal_timer.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <api/libc/alloc.h>
//#include "api/libtcpip/lwip/Netdb.h"
#include <api/libtcpip/lwip/Ip_addr.h>
#include <api/libtcpip/lwip/arch.h>
#include <api/libtcpip/lwip/Sockets.h>
#include <api/libtcpip/lwip/netif.h>
#include <api/libnic/lib_nic.h>
#include <api/libhilink/lib_hilink.h>
#include <hld/hld_dev.h>
#include <hld/net/net.h>

typedef enum
{
    HILINK_REQUEST_SETCONNECT = 0,
    HILINK_REQUEST_SETDISCONNECT,
    HILINK_REQUEST_SETENABLEAUTO,
    HILINK_REQUEST_SETDISABLEAUTO,
    HILINK_REQUEST_SETPROFILE,
    HILINK_REQUEST_GETCONNECTSTATE,
    HILINK_REQUEST_GETAUTOMODE,
    HILINK_REQUEST_GETPROFILE,

    HILINK_REQUEST_MAX,
};

typedef enum
{
    HILINK_SOCKET_READREADY = 0,
    HILINK_SOCKET_WRITEREADY,

    HILINK_SOCKER_MAX,
};

static const char *hilink_request_setcommonline = 
                "x-requested-with: XMLHttpRequest\r\n"\
                "Accept-Language: zh-cn\r\n"\
                "Referer: http://192.168.1.1/html/home.html\r\n"\
                "Accept: */*\r\n"\
                "Content-Type: application/x-www-form-urlencoded\r\n"\
                "Accept-Encoding: gzip, deflate\r\n"\
                "Host: 192.168.1.1\r\n"\
                "Content-Length: %d\r\n"\
                "Connection: Keep-Alive\r\n"\
                "Cache-Control: no-cache\r\n"\
                "\r\n";
            
static const char *hilink_setconnectactive_requestline = 
                "POST /api/dialup/dial HTTP/1.1\r\n";

static const char *hilink_setconnectactive_contentline = 
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"\
                "<request>"\
                    "<Action>%d</Action>"\
                "</request>";

static const char *hilink_setautomode_requestline = 
                "POST /api/dialup/connection HTTP/1.1\r\n";

static const char *hilink_setautomode_contentline = 
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"\
                "<request>"\
                    "<RoamAutoConnectEnable>%d</RoamAutoConnectEnable>"\
                    "<AutoReconnect>%d</AutoReconnect>"\
                    "<RoamAutoReconnectEnable>%d</RoamAutoReconnectEnable>"\
                    "<ReconnectInterval>%d</ReconnectInterval>"\
                    "<MaxIdelTime>%d</MaxIdelTime>"\
                    "<ConnectMode>%d</ConnectMode>"\
                    "<MTU>%d</MTU>"\
                "</request>";

static const char *hilink_setprofile_requestline = 
                "POST /api/dialup/profiles HTTP/1.1\r\n";

static const char *hilink_setprofile_contentline = 
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"\
                "<request>"\
                    "<Delete>0</Delete>"\
                    "<SetDefault>%d</SetDefault>"\
                    "<Modify>2</Modify>"\
                    "<Profile>"\
                        "<Index>%d</Index>"\
                        "<IsValid>%d</IsValid>"\
                        "<Name>%s</Name>"\
                        "<ApnIsStatic>%d</ApnIsStatic>"\
                        "<ApnName>%s</ApnName>"\
                        "<DialupNum>%s</DialupNum>"\
                        "<Username>%s</Username>"\
                        "<Password>%s</Password>"\
                        "<AuthMode>%d</AuthMode>"\
                        "<IpIsStatic>%d</IpIsStatic>"\
                        "<IpAddress></IpAddress>"\
                        "<DnsIsStatic>%d</DnsIsStatic>"\
                        "<PrimaryDns></PrimaryDns>"\
                        "<SecondaryDns></SecondaryDns>"\
                        "<ReadOnly>%d</ReadOnly>"\
                    "</Profile>"\
                "</request>";

static const char *hilink_getconnectstate_requestline = 
                "GET /api/monitoring/status HTTP/1.1\r\n";

static const char *hilink_getautomode_requestline = 
                "GET /api/dialup/connection HTTP/1.1\r\n";

static const char *hilink_getprofile_requestline = 
                "GET /api/dialup/profiles HTTP/1.1\r\n";

static const char *hilink_request_getcommonline = 
                "x-requested-with: XMLHttpRequest\r\n"\
                "Accept-Language: zh-cn\r\n"\
                "Referer: http://192.168.1.1/html/profilesmgr.html\r\n"\
                "Accept: */*\r\n"\
                "Accept-Encoding: gzip, deflate\r\n"\
                "Host: 192.168.1.1\r\n"\
                "Connection: Keep-Alive\r\n"\
                "\r\n";

unsigned int g_ulhilinkuseflag = 0;
unsigned int g_ulhilinkplugflag = 0;
unsigned int g_ulhilinkinitflag = 0;
unsigned int g_ulhilinkautomodestatus = 0;
unsigned int g_ulhilinkprofilestatus = 0;
HILINK_INFO_STRU *g_pstrhilinkinfo = NULL;

extern int hilink_sendmessage_statechange(unsigned int ulstatechange);

int hilink_set_useflag(unsigned int uluseflag)
{
    if (HILINK_USEFLAG_MAX <= uluseflag)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }
    
    g_ulhilinkuseflag = uluseflag;
    return HILINK_OK;
}

int hilink_get_useflag(unsigned int *puluseflag)
{
    if (NULL == puluseflag)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }
    
    *puluseflag = g_ulhilinkuseflag;   
    return HILINK_OK;
}

int hilink_set_initflag(unsigned int ulinitflag)
{
    g_ulhilinkinitflag = ulinitflag;
    return HILINK_OK;
}

int hilink_get_initflag(unsigned int *pulinitflag)
{
    if (NULL == pulinitflag)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    *pulinitflag = g_ulhilinkinitflag;
    return HILINK_OK;        
}

int hilink_set_infopointer(HILINK_INFO_STRU *pstrhilinkinfo)
{
    g_pstrhilinkinfo = pstrhilinkinfo;
    return HILINK_OK;    
}

int hilink_get_infopointer(HILINK_INFO_STRU **pstrhilinkinfo)
{
    if (NULL == pstrhilinkinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }   

    *pstrhilinkinfo = g_pstrhilinkinfo;
    return HILINK_OK;
}

int hilink_set_automodetempleatestatus(unsigned int ulstatus)
{
    if (HILINK_BUFSTATUS_MAX <= ulstatus)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }
    
    g_ulhilinkautomodestatus = ulstatus;
    return HILINK_OK;
}

int hilink_get_automodetempleatestatus(unsigned int *pulstatus)
{
    if (NULL == pulstatus)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }
    
    *pulstatus = g_ulhilinkautomodestatus;
    
    return HILINK_OK;
}

int hilink_set_profiletempleatestatus(unsigned int ulstatus)
{
    if (HILINK_BUFSTATUS_MAX <= ulstatus)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }
    
    g_ulhilinkprofilestatus = ulstatus;
    return HILINK_OK;
}

int hilink_get_profiletempleatestatus(unsigned int *pulstatus)
{
    if (NULL == pulstatus)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }
    
    *pulstatus = g_ulhilinkprofilestatus;   
    return HILINK_OK;
}

int hilink_creat_socket(int *pfdsocket)
{
    int slret = 0;
    int fdsockettemp = 0;
    unsigned int ulsockblockflags = 0;

    if (NULL == pfdsocket)
    {
		HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
		return HILINK_PARA_ERR;
    }
    
    fdsockettemp = socket(AF_INET,SOCK_STREAM,0);
    if (-1 == fdsockettemp)
    {
		HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
		return HILINK_CALL_ERR;
    }

    ulsockblockflags = 1;
    slret = ioctlsocket(fdsockettemp, FIONBIO, &ulsockblockflags);
    if (slret < 0)
    {
        closesocket(fdsockettemp);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
		return HILINK_CALL_ERR;
    }

    *pfdsocket = fdsockettemp;
    return HILINK_OK;
}

int hilink_select_timeout(int fdsocket,int slsocketstate,int sltimems)
{
    int slret = 0;
    fd_set socketset;
    struct timeval strtimeval = {0};
    struct timeval *pstrtimeout = NULL;

    FD_ZERO(&socketset);
    FD_SET(fdsocket,&socketset);
    if (sltimems >= 0)
    {
        strtimeval.tv_sec = sltimems / 1000;
        strtimeval.tv_usec = (sltimems % 1000) * 1000;
        pstrtimeout = &strtimeval;
    }
    else
    {
        pstrtimeout = NULL; 
    }

    if (HILINK_SOCKET_READREADY == slsocketstate)
    {
        slret = select(fdsocket + 1,&socketset,NULL,NULL,pstrtimeout);
    }
    else
    {
        slret = select(fdsocket + 1,NULL,&socketset,NULL,pstrtimeout);
    }

    return slret;
}

int hilink_connect_server(int fdsocket,char *pcserveraddr)
{
    int slret = 0;
    int sltimems = 0;
    int slsocketerror = 0;
    int sllen = sizeof(slsocketerror);
    unsigned int ulserveraddr = 0;
    unsigned int ultickbegin = 0;
    unsigned int ultickend = 0;
    struct sockaddr_in strServerAddr = {0};

    if (NULL == pcserveraddr)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    slret = inet_aton(pcserveraddr,(struct in_addr *)(&ulserveraddr));
    if (0 == slret)
	{
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
	}

	strServerAddr.sin_family = AF_INET;
	strServerAddr.sin_port = htons(HILINK_SERVER_HTTPPORT);
	strServerAddr.sin_addr.s_addr = ulserveraddr;

    /*slret = connect(fdsocket, (struct sockaddr *)(&strServerAddr), sizeof(sockaddr_in));*/
    slret = connect(fdsocket, (struct sockaddr *)(&strServerAddr), sizeof(strServerAddr));
    if ((slret < 0) && (SOCKERRNO != EINPROGRESS))
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    if (slret == 0) 
    {
        return HILINK_OK;
    }

    sltimems = 5000;
    ultickbegin = osal_get_tick();
    slret = hilink_select_timeout(fdsocket, HILINK_SOCKET_WRITEREADY,sltimems);
    if (slret > 0)
    {
        slret = getsockopt(fdsocket, SOL_SOCKET, SO_ERROR, &slsocketerror, (socklen_t *)(&sllen));
        if (slret < 0)
        {
            HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
            slret = HILINK_CALL_ERR;
        }
        else
        {
            slret = HILINK_OK;
        }

        if (slsocketerror)
        {
            HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
            slret = HILINK_CALL_ERR;
        }
    }
    else if (slret == 0) 
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        slret = HILINK_TIMEOUT_ERR;
    }
    else 
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        slret = HILINK_CALL_ERR;
    }

    ultickend = osal_get_tick();
    //HILINK_PRINT("%s:begin=%d,finish=%d,time=%d.\r\n",__FUNCTION__,ultickbegin,ultickend,ultickend-ultickbegin);
    return slret;
}

int hilink_send_requestbuf(int fdsocket,unsigned int ullen,char *pcrequestbuf)
{
    int slret = 0;
    int sltimeout = 5000;
    unsigned int ulsendlen = 0;

    if ((-1 == fdsocket)||(NULL == pcrequestbuf)||(0 == ullen))
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    slret = hilink_select_timeout(fdsocket,HILINK_SOCKET_WRITEREADY,sltimeout);
    if (0 > slret)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    
    ulsendlen = send(fdsocket,pcrequestbuf,ullen,0);
    if (ullen != ulsendlen)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    //HILINK_PRINT("%s",pcrequestbuf);
    return HILINK_OK;
}

int hilink_form_request(unsigned int ulrequesttype,unsigned int ulbuflen,char *pcrequestbuf,char *pcconfiginfo)
{
    int slret = 0;
    unsigned int ultotallen = 0;
    unsigned int ulrequestlinelen = 0;
    unsigned int ulcommonlinelen = 0;
    unsigned int ulcontentlinelen = 0;
    unsigned int ulbuftemplen = 0;
    unsigned int ulcontenttemplen = 0;
    unsigned int ulautomodebufstatus = 0;
    unsigned int ulprofilebufstatus = 0;
    char *pcbuftemp = NULL;
    char *pccontenttemp = NULL;
    char *pcrequesetline = NULL;
    char *pccommonline = NULL;
    char *pccontentline = NULL;
    char *pcsetprofile = NULL;
    char *pcsetautomode = NULL;
    HILINK_SETCONNECT_STATE_STRU *pstrsetconnectstate = NULL;
    HILINK_AUTOMODE_INFO_STRU *pstrautomodeinfo = NULL;
    HILINK_PROFILE_INFO_STRU *pstrprofileinfo = NULL;
    HILINK_INFO_STRU *pstrhilinkinfo = NULL;

    if ((ulrequesttype >= HILINK_REQUEST_MAX)||(0 == ulbuflen)||(NULL == pcrequestbuf))
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    if ((HILINK_REQUEST_SETPROFILE >= ulrequesttype)&&(NULL == pcconfiginfo))
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    (void)hilink_get_infopointer(&pstrhilinkinfo);
    if (NULL == pstrhilinkinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    
    ulbuftemplen = 1024;
    pcbuftemp = (char *)malloc(ulbuftemplen);
    if (NULL == pcbuftemp)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_MALLOC_ERR;
    }
    MEMSET(pcbuftemp,0,ulbuftemplen);

    ulcontenttemplen = 2 * 1024;
    pccontenttemp = (char *)malloc(ulcontenttemplen);
    if (NULL == pccontenttemp)
    {
        free(pcbuftemp);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_MALLOC_ERR;
    }
    MEMSET(pccontenttemp,0,ulcontenttemplen);

    switch (ulrequesttype)
    {
        case HILINK_REQUEST_SETCONNECT:
        case HILINK_REQUEST_SETDISCONNECT:
        {
            pcrequesetline = hilink_setconnectactive_requestline;
            pccontentline = hilink_setconnectactive_contentline;
            pstrsetconnectstate = (HILINK_SETCONNECT_STATE_STRU *)(pcconfiginfo);
            snprintf(pccontenttemp,ulcontenttemplen,pccontentline,pstrsetconnectstate->ulsetconnectstate);          
        }
        break;

        case HILINK_REQUEST_SETENABLEAUTO:
        case HILINK_REQUEST_SETDISABLEAUTO:
        {
            pcsetautomode = pstrhilinkinfo->pcsetautomodebuf;
            if (NULL == pcsetautomode)
            {
                HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
                return HILINK_PARA_ERR;
            } 
            
            hilink_get_automodetempleatestatus(&ulautomodebufstatus);
            if (HILINK_BUFSTATUS_IDLE != ulautomodebufstatus)
            {
                HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
                return HILINK_CALL_ERR;
            }

            (void)hilink_set_automodetempleatestatus(HILINK_BUFSTATUS_BUSY);
            pstrautomodeinfo = (HILINK_AUTOMODE_INFO_STRU *)(pcconfiginfo);
            pcrequesetline = hilink_setautomode_requestline;
            pccontentline = pcsetautomode;      
            snprintf(pccontenttemp,ulcontenttemplen,pccontentline,pstrautomodeinfo->ulautomode);
            (void)hilink_set_automodetempleatestatus(HILINK_BUFSTATUS_IDLE);
        }
        break;

        case HILINK_REQUEST_SETPROFILE:
        {          
            pcsetprofile = pstrhilinkinfo->pcsetprofilebuf;
            if (NULL == pcsetprofile)
            {
                HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
                return HILINK_PARA_ERR;
            } 

            hilink_get_profiletempleatestatus(&ulprofilebufstatus);
            if (HILINK_BUFSTATUS_IDLE != ulprofilebufstatus)
            {
                HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
                return HILINK_CALL_ERR;
            }

            (void)hilink_set_profiletempleatestatus(HILINK_BUFSTATUS_BUSY);
            pstrprofileinfo = (HILINK_PROFILE_INFO_STRU *)(pcconfiginfo);
            pcrequesetline = hilink_setprofile_requestline;
            pccontentline = pcsetprofile;
            snprintf(pccontenttemp,ulcontenttemplen,pccontentline,pstrprofileinfo->ulapnno,pstrprofileinfo->acapn,pstrprofileinfo->acuser,pstrprofileinfo->acpasswd);
            (void)hilink_set_profiletempleatestatus(HILINK_BUFSTATUS_IDLE);
        }
        break;

        case HILINK_REQUEST_GETCONNECTSTATE:
        {
            pcrequesetline = hilink_getconnectstate_requestline;
        }
        break;

        case HILINK_REQUEST_GETAUTOMODE:
        {
            pcrequesetline = hilink_getautomode_requestline;
        }
        break;

        case HILINK_REQUEST_GETPROFILE:
        {
            pcrequesetline = hilink_getprofile_requestline;
        }
        break;

        default:
        {
            free(pcbuftemp);
            free(pccontenttemp);
            HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
            return HILINK_PARA_ERR;
        }              
    }

    if (HILINK_REQUEST_SETPROFILE >= ulrequesttype)
    {   
        pccommonline = hilink_request_setcommonline;    
        ulcontentlinelen = strlen(pccontenttemp);
        snprintf(pcbuftemp,ulbuftemplen,pccommonline,ulcontentlinelen);
        ulcommonlinelen = strlen(pcbuftemp);
        ulrequestlinelen = strlen(pcrequesetline);
        ultotallen = ulrequestlinelen + ulcommonlinelen + ulcontentlinelen;
        if (ultotallen > ulbuflen)
        {
            free(pcbuftemp);
            free(pccontenttemp);
            HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
            return HILINK_SPACESMALL_ERR;
        }
        snprintf(pcrequestbuf,ulbuflen,pcrequesetline);
        snprintf(pcrequestbuf + ulrequestlinelen,ulbuflen - ulrequestlinelen,pcbuftemp);
        snprintf(pcrequestbuf + ulrequestlinelen + ulcommonlinelen,ulbuflen - ulrequestlinelen - ulcommonlinelen,pccontenttemp); 
    }
    else
    {
        pccommonline = hilink_request_getcommonline;
        ulrequestlinelen = strlen(pcrequesetline);
        ulcommonlinelen = strlen(pccommonline);
        ulcontentlinelen = 0;
        ultotallen = ulrequestlinelen + ulcommonlinelen + ulcontentlinelen;
        if (ultotallen > ulbuflen)
        {
            free(pcbuftemp);
            free(pccontenttemp);
            HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
            return HILINK_SPACESMALL_ERR;
        }
        snprintf(pcrequestbuf,ulbuflen,pcrequesetline);
        snprintf(pcrequestbuf + ulrequestlinelen,ulbuflen - ulrequestlinelen,pccommonline);
    }

    free(pcbuftemp);
    free(pccontenttemp);
    return HILINK_OK;
}

int hilink_receive_responsebuf(int fdsocket,unsigned int ullen,char *pcbuf,unsigned int *pulactread)
{
    int slret = 0;
    int sltimeout = 5000;
    unsigned int ulreadnum = 0;

    if ((-1 == fdsocket)||(0 == ullen)||(NULL == pcbuf)||(NULL == pulactread))
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }
    
    while (ulreadnum < ullen)
    {
        slret = hilink_select_timeout(fdsocket,HILINK_SOCKET_READREADY,sltimeout);
        if (0 == slret)
        {
            *pulactread = ulreadnum;
            HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
            return HILINK_TIMEOUT_ERR;
        }
        else if (0 > slret)
        {
            *pulactread = ulreadnum;
            HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
            return HILINK_CALL_ERR;
        }

        slret = recv(fdsocket,pcbuf + ulreadnum,ullen - ulreadnum,0);
        if (0 == slret)
        {
            *pulactread = ulreadnum;
            HILINK_PRINT("%s:%d error.\r\n",__FUNCTION__,__LINE__);
            return HILINK_EOS_ERR;
        }
        else if (0 > slret)
        {
            *pulactread = ulreadnum;
            HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
            return HILINK_CALL_ERR;
        }

        ulreadnum += slret;     
    }

    return HILINK_OK;
}

int hilink_receive_responsehead(int fdsocket,unsigned int ullen,char *pcbuf,unsigned int *pulheadlen)
{
    int slret = 0;
    unsigned int ulactread = 0;
    unsigned int ulreadlen = 0;
    unsigned int ultemp = 0;
    unsigned int ulendlineflag = 0;

    if ((-1 == fdsocket)||(0 == ullen)||(NULL == pcbuf)||(NULL == pulheadlen))
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    while (1)
    {
        slret = hilink_receive_responsebuf(fdsocket, 1, &pcbuf[ulreadlen],&ulactread);
        if (HILINK_OK != slret)
        {
            HILINK_PRINT("%s:%d error.\r\n",__FUNCTION__,__LINE__);
            return HILINK_CALL_ERR;
        }

        if ('\012' == pcbuf[ulreadlen])
        {
            ultemp = ulreadlen - 1;
            if ('\015' == pcbuf[ultemp])
            {
                if (ulendlineflag)
                {
                    ulendlineflag = 0;
                }
                else
                {
                    break;
                }
            }
        }
        else
        {
            if (('\015' != pcbuf[ulreadlen])&&(0 == ulendlineflag))
            {
                ulendlineflag = 1;
            }
        } 

        ulreadlen ++;
        if (ulreadlen > ullen)
        {
            HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
            return HILINK_SPACESMALL_ERR;
        }       
    }

    *pulheadlen = ulreadlen;
    return HILINK_OK;
}

int hilink_receive_response(int fdsocket,unsigned int ullen,char *pcresponsebuf)
{
    int slret = 0;
    unsigned int ulactread = 0;
    unsigned int ulheadlen = 0;
    unsigned int ulcontentlen = 0;
    char *pclengthbegin = NULL;

    if ((-1 == fdsocket)||(NULL == pcresponsebuf)||(0 == ullen))
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    MEMSET(pcresponsebuf,0,ullen);
    slret = hilink_receive_responsehead(fdsocket,ullen,pcresponsebuf,&ulheadlen);
    if (HILINK_OK != slret)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return slret;
    }

    pclengthbegin = strstr(pcresponsebuf,"Content-Length:");
    if (NULL == pclengthbegin)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    sscanf(pclengthbegin,"Content-Length:%d\r\n",&ulcontentlen);
    if (ullen < ulheadlen + ulcontentlen)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_SPACESMALL_ERR;
    }

    //HILINK_PRINT("Content-Length:%d\r\n",ulcontentlen);
    slret = hilink_receive_responsebuf(fdsocket,ulcontentlen,pcresponsebuf + ulheadlen, &ulactread);
    if (HILINK_OK != slret)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    //HILINK_PRINT("%s\r\n",pcresponsebuf);
    return HILINK_OK;
}

int hilink_send_request(unsigned int ulrequesttype,unsigned int ullen,char *pcresponsebuf,char *pcconfiginfo)
{
    int slret = 0;
    int fdsocket = 0;
    unsigned int ulbuflen = 0;
    char *pcrequestbuf = NULL;
    char *pcserveraddr = NULL;

    if ((HILINK_REQUEST_MAX <= ulrequesttype)||(NULL == pcresponsebuf)||(0 == ullen))
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    ulbuflen = HILINK_REQUEST_BUFLEN;
    pcrequestbuf = (char *)malloc(ulbuflen);
    if (NULL == pcrequestbuf)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
		return HILINK_MALLOC_ERR;
    }
    MEMSET(pcrequestbuf,0,ulbuflen);

    slret = hilink_creat_socket(&fdsocket);
    if (HILINK_OK != slret)
    {
        free(pcrequestbuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
		return HILINK_CALL_ERR;
    }
    
    pcserveraddr = "192.168.1.1";
    slret = hilink_connect_server(fdsocket, pcserveraddr);
    if (HILINK_OK != slret)
    {
        closesocket(fdsocket);
        free(pcrequestbuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
		return HILINK_CALL_ERR;
    }

    slret = hilink_form_request(ulrequesttype,ulbuflen,pcrequestbuf,pcconfiginfo);
    if (HILINK_OK != slret)
    {
        closesocket(fdsocket);
        free(pcrequestbuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
		return HILINK_CALL_ERR;
    }
    
    slret = hilink_send_requestbuf(fdsocket,ulbuflen,pcrequestbuf);
    if (HILINK_OK != slret)
    {
        closesocket(fdsocket);
        free(pcrequestbuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
		return HILINK_CALL_ERR;
    }

    slret = hilink_receive_response(fdsocket, ullen, pcresponsebuf);
    if (HILINK_OK != slret)
    {
        closesocket(fdsocket);
        free(pcrequestbuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
		return HILINK_CALL_ERR;
    }

    //HILINK_PRINT("%s.\r\n",pcrequestbuf);
    //HILINK_PRINT("%s.\r\n",pcresponsebuf);

    closesocket(fdsocket);
    free(pcrequestbuf);
    return HILINK_OK;
}

int hilink_response_check(char *pcresponsebuf)
{
    int slret = 0;
    unsigned int ulhttpver = 0;
    unsigned int ulhttpsub = 0;
    unsigned int ulhttpcode = 0;
    char achttpstatus[31] = {0};

    if (NULL == pcresponsebuf)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    slret = sscanf(pcresponsebuf,"HTTP/%d.%d %d %30[^\015\012]",&ulhttpver,&ulhttpsub,&ulhttpcode,achttpstatus);
    if (4 != slret) 
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    if ((ulhttpcode < 200)||(ulhttpcode >= 300))
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_HTTPCODE_ERR;
    }

    return HILINK_OK;
}

int hilink_response_getvalue(char *pcfind,char *pcsource,unsigned int *pulvalue)
{
    int slret = 0;
    unsigned int ullen = 0;
    unsigned int ultemp = 0;
    char *pcpostion = NULL;
    
    if ((NULL == pcfind)||(NULL == pcsource)||(NULL == pulvalue))
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    pcpostion = strstr(pcsource,pcfind);
    if (NULL == pcpostion)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_NOFIND_ERR;
    }

    ullen = strlen(pcfind);
    slret = sscanf(pcpostion + ullen,"%d",&ultemp);
    if (1 != slret)
    {
        *pulvalue = 0xffffffff;
        HILINK_PRINT("%s:%d:not find value.\r\n",__FUNCTION__,__LINE__);
        return HILINK_NOFINDVALUE_ERR;
    }

    *pulvalue = ultemp;
    return HILINK_OK;
}

int hilink_form_setprofiletemplate(char *pcresponsebuf)
{
    int slret = 0;
    unsigned int ulindex = 0;
    unsigned int ultotallen = 0;
    unsigned int ullen = 0;
    unsigned int ullen1 = 0;
    unsigned int ullen2 = 0;
    unsigned int ullen3 = 0;
    unsigned int ulsetprofilelen = 0;
    char acfindstring[50] = {0};
    char *pcsetprofile = NULL;
    char *pcposbegin1 = NULL;
    char *pcposend1 = NULL;
    char *pcposbegin2 = NULL;
    char *pcposend2 = NULL;
    char *pcposbegin3 = NULL;
    char *pcposend3 = NULL;
    char *pcposlast = NULL;
    HILINK_INFO_STRU *pstrhilinkinfo = NULL;
    
    char *pcstring1 = "<ApnName>%s</ApnName>";
    char *pcstring2 = "<Username>%s</Username><Password>%s</Password>";
    
    char *pcbegin = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"\
                    "<request>"\
                    "<Delete>0</Delete>"\
                        "<SetDefault>%d</SetDefault>"\
                        "<Modify>2</Modify>"\
                        "<Profile>";
    
    char *pcend =       "</Profile>"\
                    "</request>"; 

    if (NULL == pcresponsebuf)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    (void)hilink_get_infopointer(&pstrhilinkinfo);   
    if (NULL == pstrhilinkinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    ulsetprofilelen = pstrhilinkinfo->ulsetprofilebuflen;
    pcsetprofile = pstrhilinkinfo->pcsetprofilebuf;

    slret = hilink_response_getvalue("<CurrentProfile>",pcresponsebuf, &ulindex);
    if (HILINK_OK != slret)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    sprintf(acfindstring,"<Index>%d</Index>",ulindex);
    pcposbegin1 = strstr(pcresponsebuf,acfindstring);
    if (NULL == pcposbegin1)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    pcposlast = strstr(pcposbegin1,"</Profile>");
    if (NULL == pcposlast)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    
    pcposend1 = strstr(pcposbegin1,"<ApnName");
    if ((NULL == pcposend1)||(pcposlast < pcposend1))
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    ullen1 = pcposend1 - pcposbegin1;

    pcposbegin2 = pcposend1 + strlen("<ApnName");
    if ('/' == *pcposbegin2)
    {
        pcposbegin2 += strlen("/>");
    }
    else if ('>' == *pcposbegin2)
    {
        pcposbegin2 = strstr(pcposbegin2,"</ApnName>");
        if (NULL == pcposbegin2)
        {
            HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
            return HILINK_CALL_ERR;
        }
        pcposbegin2 += strlen("</ApnName>");
    }
    else
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    pcposend2 = strstr(pcposbegin2,"<Username");
    if ((NULL == pcposend2)||(pcposlast < pcposend2))
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    ullen2 = pcposend2 - pcposbegin2;

    pcposbegin3 = strstr(pcposend2,"Password");
    pcposbegin3 += strlen("Password");
    if ('/' == *pcposbegin3)
    {
        pcposbegin3 += strlen("/>");
    }
    else if ('>' == *pcposbegin3)
    {
        pcposbegin3 = strstr(pcposbegin3,"</Password>");
        if (NULL == pcposbegin3)
        {
            HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
            return HILINK_CALL_ERR;
        }
        pcposbegin3 += strlen("</Password>");
    }
    else
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    
    pcposend3 = pcposlast;
    ullen3 = pcposend3 - pcposbegin3;

    ultotallen = strlen(pcbegin) + strlen(pcend) + strlen(pcstring1) + strlen(pcstring2)\
                + ullen1 + ullen2 + ullen3;
    if (ultotallen >= ulsetprofilelen)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_SPACESMALL_ERR;
    }

    MEMCPY(pcsetprofile,pcbegin,strlen(pcbegin));
    pcsetprofile += strlen(pcbegin);
    
    MEMCPY(pcsetprofile,pcposbegin1,ullen1);
    pcsetprofile += ullen1;
    
    MEMCPY(pcsetprofile,pcstring1,strlen(pcstring1));
    pcsetprofile += strlen(pcstring1);
    
    MEMCPY(pcsetprofile,pcposbegin2,ullen2);
    pcsetprofile += ullen2;

    MEMCPY(pcsetprofile,pcstring2,strlen(pcstring2));
    pcsetprofile += strlen(pcstring2);

    MEMCPY(pcsetprofile,pcposbegin3,ullen3);
    pcsetprofile += ullen3;
    
    MEMCPY(pcsetprofile,pcend,strlen(pcend));
    pcsetprofile += strlen(pcend);

    //HILINK_PRINT("%s.\r\n",pstrhilinkinfo->pcsetprofilebuf);
    return HILINK_OK;
}

int hilink_form_setautomodetemplate(char *pcresponsebuf)
{
    unsigned int ullen1 = 0;
    unsigned int ullen2 = 0;
    unsigned int ultotallen = 0;
    unsigned int ulsetautomodelen = 0;
    char *pcsetautomode = NULL;
    char *pcposbegin1 = NULL;
    char *pcposend1 = NULL;
    char *pcposbegin2 = NULL;
    char *pcposend2 = NULL;
    HILINK_INFO_STRU *pstrhilinkinfo = NULL;

    char *pcstring = "<ConnectMode>%d</ConnectMode>";
    
    char *pcbegin = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"\
                    "<request>";
    
    char *pcend = "</request>";

    if (NULL == pcresponsebuf)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    (void)hilink_get_infopointer(&pstrhilinkinfo);   
    if (NULL == pstrhilinkinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    ulsetautomodelen = pstrhilinkinfo->ulsetautomodebuflen;
    pcsetautomode = pstrhilinkinfo->pcsetautomodebuf;

    pcposbegin1 = strstr(pcresponsebuf,"<response>");
    if (NULL == pcposbegin1)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    pcposbegin1 += strlen("<response>");

    pcposend1 = strstr(pcposbegin1,"<ConnectMode>");
    if (NULL == pcposend1)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    ullen1 = pcposend1 - pcposbegin1;

    pcposbegin2 = strstr(pcposend1,"</ConnectMode>");
    if (NULL == pcposbegin2)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    pcposbegin2 += strlen("</ConnectMode>");

    pcposend2 = strstr(pcposbegin2,"</response>");
    if (NULL == pcposend2)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    ullen2 = pcposend2 - pcposbegin2;

    ultotallen = strlen(pcbegin) + strlen(pcend) + strlen(pcstring) + ullen1 + ullen2;
    if (ultotallen >= ulsetautomodelen)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_SPACESMALL_ERR;
    }

    MEMCPY(pcsetautomode,pcbegin,strlen(pcbegin));
    pcsetautomode += strlen(pcbegin);
    
    MEMCPY(pcsetautomode,pcposbegin1,ullen1);
    pcsetautomode += ullen1;
    
    MEMCPY(pcsetautomode,pcstring,strlen(pcstring));
    pcsetautomode += strlen(pcstring);
    
    MEMCPY(pcsetautomode,pcposbegin2,ullen2);
    pcsetautomode += ullen2;

    MEMCPY(pcsetautomode,pcend,strlen(pcend));
    pcsetautomode += strlen(pcend);
    
    //HILINK_PRINT("%s.\r\n",pstrhilinkinfo->pcsetautomodebuf);
    return HILINK_OK;
}


int hilink_response_getstring(char *pcfind,char *pcsource,char *pcsourceend,unsigned int ullen,char *pcdest,unsigned int *pulactlen)
{
    int slret = 0;
    unsigned int ulactlen = 0;
    char *pcpostionbegin = NULL;
    char *pcpostionend = NULL;
    
    if ((NULL == pcfind)||(NULL == pcsource)||(NULL == pcdest)||(NULL == pulactlen))
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    pcpostionbegin = strstr(pcsource,pcfind);
    if (NULL == pcpostionbegin)
    {
        HILINK_PRINT("%s:%d:%s no find.\r\n",__FUNCTION__,__LINE__,pcfind);
        return HILINK_NOFIND_ERR;
    }
    
    pcpostionbegin += strlen(pcfind);
    if ((NULL != pcsourceend)&&(pcpostionbegin >= pcsourceend))
    {
        HILINK_PRINT("%s:%d:%s no find.\r\n",__FUNCTION__,__LINE__,pcfind);
        return HILINK_NOFIND_ERR;
    }
    if ('/' == *pcpostionbegin)
    {
        HILINK_PRINT("%s:%d:%s no value.\r\n",__FUNCTION__,__LINE__,pcfind);
        return HILINK_OK;
    }   

    pcpostionbegin += 1;
    pcpostionend = strstr(pcpostionbegin,"</");
    if (NULL == pcpostionend)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_NOFIND_ERR;
    }

    ulactlen = pcpostionend - pcpostionbegin;
    if (ullen < ulactlen)
    {
        ulactlen = ullen - 1;
        HILINK_PRINT("%s:%d:space small.\r\n",__FUNCTION__,__LINE__);
    }

    MEMCPY(pcdest,pcpostionbegin,ulactlen);
    *pulactlen = ulactlen;
    return HILINK_OK;
}

int hilink_setprofileinfo_tolocall(HILINK_PROFILE_INFO_STRU strprofileinfo)
{
    HILINK_INFO_STRU *pstrhilinkinfo = NULL;
    
    (void)hilink_get_infopointer(&pstrhilinkinfo);
    if (NULL == pstrhilinkinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    MEMCPY(&(pstrhilinkinfo->strprofileinfo),&strprofileinfo,sizeof(HILINK_PROFILE_INFO_STRU));
    
    return HILINK_OK;
}

int hilink_setautomodeinfo_tolocall(HILINK_AUTOMODE_INFO_STRU strautomodeinfo)
{
    HILINK_INFO_STRU *pstrhilinkinfo = NULL;
    
    (void)hilink_get_infopointer(&pstrhilinkinfo);
    if (NULL == pstrhilinkinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    MEMCPY(&(pstrhilinkinfo->strautomodeinfo),&strautomodeinfo,sizeof(HILINK_AUTOMODE_INFO_STRU));
    
    return HILINK_OK;
}

int hilink_setconnectstate_tolocall(HILINK_CONNECTSTATE_INFO_STRU strconnectstateinfo)
{
    HILINK_INFO_STRU *pstrhilinkinfo = NULL;
    
    (void)hilink_get_infopointer(&pstrhilinkinfo);
    if (NULL == pstrhilinkinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    osal_mutex_lock(pstrhilinkinfo->mutex_connectstateinfo, OSAL_WAIT_FOREVER_TIME);
    MEMCPY(&(pstrhilinkinfo->strconnectstateinfo),&strconnectstateinfo,sizeof(HILINK_CONNECTSTATE_INFO_STRU));
    pstrhilinkinfo->strconnectstateinfo.ulupdateflag = 1;
    osal_mutex_unlock(pstrhilinkinfo->mutex_connectstateinfo);
    
    return HILINK_OK;
}

int hilink_setprofileinfo_toserver(HILINK_PROFILE_INFO_STRU strprofileinfo)
{
    int slret = 0;
    unsigned int ulresponsebuflen = 0;
    char *pcresponsebuf = NULL;
   
    ulresponsebuflen = HILINK_RESPONSE_BUFLEN;
    pcresponsebuf = (char *)malloc(ulresponsebuflen);
    if (NULL == pcresponsebuf)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_MALLOC_ERR;
    }

    slret = hilink_send_request(HILINK_REQUEST_SETPROFILE,ulresponsebuflen,pcresponsebuf,&strprofileinfo);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_check(pcresponsebuf);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    free(pcresponsebuf);
    return HILINK_OK;
}

int hilink_setautomodeinfo_toserver(HILINK_AUTOMODE_INFO_STRU strautomodeinfo)
{
    int slret = 0;
    unsigned int ulrequesttype = 0;
    unsigned int ulresponsebuflen = 0;
    char *pcresponsebuf = NULL;
    
    if (strautomodeinfo.ulautomode >= HILINK_ATUOMODE_MAX)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    if (HILINK_AUTOMODE_ENABLE == strautomodeinfo.ulautomode)
    {
        ulrequesttype = HILINK_REQUEST_SETENABLEAUTO;
    }
    else
    {
        ulrequesttype = HILINK_REQUEST_SETDISABLEAUTO;
    }
    
    ulresponsebuflen = HILINK_RESPONSE_BUFLEN;
    pcresponsebuf = (char *)malloc(ulresponsebuflen);
    if (NULL == pcresponsebuf)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_MALLOC_ERR;
    }

    slret = hilink_send_request(ulrequesttype,ulresponsebuflen,pcresponsebuf,&strautomodeinfo);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_check(pcresponsebuf);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    free(pcresponsebuf);
    return HILINK_OK;
}

int hilink_setconnectstate_toserver(HILINK_SETCONNECT_STATE_STRU strsetconnectstate)
{
    int slret = 0;
    unsigned int ulrequesttype = 0;
    unsigned int ulresponsebuflen = 0;
    char *pcresponsebuf = NULL;
    
    if (strsetconnectstate.ulsetconnectstate >= HILINK_CONNECTSTATE_SETMAX)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    if (HILINK_CONNECTSTATE_SETDISCONNECT == strsetconnectstate.ulsetconnectstate)
    {
        ulrequesttype = HILINK_REQUEST_SETDISCONNECT;
    }
    else
    {
        ulrequesttype = HILINK_REQUEST_SETCONNECT;
    }
    
    ulresponsebuflen = HILINK_RESPONSE_BUFLEN;
    pcresponsebuf = (char *)malloc(ulresponsebuflen);
    if (NULL == pcresponsebuf)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_MALLOC_ERR;
    }

    slret = hilink_send_request(ulrequesttype,ulresponsebuflen,pcresponsebuf,&strsetconnectstate);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_check(pcresponsebuf);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    free(pcresponsebuf);
    return HILINK_OK;
}

int hilink_getprofileinfo_fromlocall(HILINK_PROFILE_INFO_STRU *pstrprofileinfo)
{
    HILINK_INFO_STRU *pstrhilinkinfo = NULL;
    
    if (NULL == pstrprofileinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }
   
    (void)hilink_get_infopointer(&pstrhilinkinfo);
    if (NULL == pstrhilinkinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    MEMCPY(pstrprofileinfo,&(pstrhilinkinfo->strprofileinfo),sizeof(HILINK_PROFILE_INFO_STRU));
    return HILINK_OK;    
}

int hilink_getautomodeinfo_fromlocall(HILINK_AUTOMODE_INFO_STRU *pstrautomodeinfo)
{
    HILINK_INFO_STRU *pstrhilinkinfo = NULL;
    
    if (NULL == pstrautomodeinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }
   
    (void)hilink_get_infopointer(&pstrhilinkinfo);
    if (NULL == pstrhilinkinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    MEMCPY(pstrautomodeinfo,&(pstrhilinkinfo->strautomodeinfo),sizeof(HILINK_AUTOMODE_INFO_STRU));    

    return HILINK_OK;  
}

int hilink_getconnectstate_fromlocall(HILINK_CONNECTSTATE_INFO_STRU *pstrconnectstateinfo)
{
    HILINK_INFO_STRU *pstrhilinkinfo = NULL;
    
    if (NULL == pstrconnectstateinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }
   
    (void)hilink_get_infopointer(&pstrhilinkinfo);
    if (NULL == pstrhilinkinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    
    osal_mutex_lock(pstrhilinkinfo->mutex_connectstateinfo, OSAL_WAIT_FOREVER_TIME);
    if (0 == pstrhilinkinfo->strconnectstateinfo.ulupdateflag)
    {
        osal_mutex_unlock(pstrhilinkinfo->mutex_connectstateinfo);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_UPDATE_ERR;
    }
    MEMCPY(pstrconnectstateinfo,&(pstrhilinkinfo->strconnectstateinfo),sizeof(HILINK_CONNECTSTATE_INFO_STRU));
    osal_mutex_unlock(pstrhilinkinfo->mutex_connectstateinfo);
    
    return HILINK_OK;  
}

int hilink_getprofileinfo_fromserver(HILINK_PROFILE_INFO_STRU *pstrprofileinfo)
{
    int slret = 0;
    unsigned int ulactlen = 0;
    unsigned int ulresponsebuflen = 0;
    unsigned int ulprofilestatus = 0;
    char acfindstring[50] = {0};
    char *pcpostionbegin = NULL;
    char *pcpostionend = NULL;
    char *pcresponsebuf = NULL;

    if (NULL == pstrprofileinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    ulresponsebuflen = HILINK_RESPONSE_BUFLEN;
    pcresponsebuf = (char *)malloc(ulresponsebuflen);
    if (NULL == pcresponsebuf)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_MALLOC_ERR;
    }
    MEMSET(pcresponsebuf,0,ulresponsebuflen);

    slret = hilink_send_request(HILINK_REQUEST_GETPROFILE,ulresponsebuflen,pcresponsebuf,NULL);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_check(pcresponsebuf);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getvalue("<CurrentProfile>",pcresponsebuf, &(pstrprofileinfo->ulapnno));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    sprintf(acfindstring,"<Index>%d</Index>",pstrprofileinfo->ulapnno);
    HILINK_PRINT("acfindstring:%s\r\n",acfindstring);
    pcpostionbegin = strstr(pcresponsebuf,acfindstring);
    if (NULL == pcpostionbegin)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    pcpostionend = strstr(pcpostionbegin,"</Profile>");
    if (NULL == pcpostionend)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    #if 0
    slret = hilink_response_getvalue("<IsValid>",pcpostionbegin,&(pstrprofileinfo->ulisvalid));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getstring("<Name>",pcpostionbegin,pcpostionend,HILINK_PROFILE_LEN,pstrprofileinfo->acname,&ulactlen);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getvalue("<ApnIsStatic>",pcpostionbegin,&(pstrprofileinfo->ulapnisstatic));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getstring("<ApnName>",pcpostionbegin,pcpostionend,HILINK_PROFILE_LEN,pstrprofileinfo->acapn,&ulactlen);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    
    slret = hilink_response_getstring("<DialupNum>",pcpostionbegin,pcpostionend,HILINK_PROFILE_LEN,pstrprofileinfo->acdialupnum,&ulactlen);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getstring("<Username>",pcpostionbegin,pcpostionend,HILINK_PROFILE_LEN,pstrprofileinfo->acuser,&ulactlen);
    if ((HILINK_OK != slret)&&(HILINK_NOFIND_ERR != slret))
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getstring("<Password>",pcpostionbegin,pcpostionend,HILINK_PROFILE_LEN,pstrprofileinfo->acpasswd,&ulactlen);
    if ((HILINK_OK != slret)&&(HILINK_NOFIND_ERR != slret))
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getvalue("<AuthMode>",pcpostionbegin,&(pstrprofileinfo->ulauthmode));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getvalue("<IpIsStatic>",pcpostionbegin,&(pstrprofileinfo->ulipisstatic));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getvalue("<DnsIsStatic>",pcpostionbegin,&(pstrprofileinfo->uldnsistatic));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getvalue("<ReadOnly>",pcpostionbegin,&(pstrprofileinfo->ulreadonly));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    #endif
    slret = hilink_response_getstring("Name",pcpostionbegin,pcpostionend,HILINK_PROFILE_LEN,pstrprofileinfo->acname,&ulactlen);
    if (HILINK_OK != slret)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
    }
    
    slret = hilink_response_getstring("ApnName",pcpostionbegin,pcpostionend,HILINK_PROFILE_LEN,pstrprofileinfo->acapn,&ulactlen);
    if (HILINK_OK != slret)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
    }

    slret = hilink_response_getstring("Username",pcpostionbegin,pcpostionend,HILINK_PROFILE_LEN,pstrprofileinfo->acuser,&ulactlen);
    if (HILINK_OK != slret)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
    }

    slret = hilink_response_getstring("Password",pcpostionbegin,pcpostionend,HILINK_PROFILE_LEN,pstrprofileinfo->acpasswd,&ulactlen);
    if (HILINK_OK != slret)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
    }
    
    HILINK_PRINT("INDEX:%d,name:%s,APN:%s,USER:%s,PASS:%s.\r\n",pstrprofileinfo->ulapnno,pstrprofileinfo->acname,pstrprofileinfo->acapn,\
                                                    pstrprofileinfo->acuser,pstrprofileinfo->acpasswd);

    (void)hilink_get_profiletempleatestatus(&ulprofilestatus);
    if (HILINK_BUFSTATUS_NOINIT == ulprofilestatus)
    {        
        slret = hilink_form_setprofiletemplate(pcresponsebuf);
        if (HILINK_OK != slret)
        {
            (void)hilink_set_profiletempleatestatus(HILINK_BUFSTATUS_NOINIT);  
            HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        }
        else
        {
            (void)hilink_set_profiletempleatestatus(HILINK_BUFSTATUS_IDLE);
        }
    }
          
    free(pcresponsebuf);
    return HILINK_OK;
}

int hilink_getautomodeinfo_fromserver(HILINK_AUTOMODE_INFO_STRU *pstrautomodeinfo)
{
    int slret = 0;
    unsigned int ulresponsebuflen = 0;
    unsigned int ulautomodestatus = 0;
    char *pcresponsebuf = NULL;

    if (NULL == pstrautomodeinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    ulresponsebuflen = HILINK_RESPONSE_BUFLEN;
    pcresponsebuf = (char *)malloc(ulresponsebuflen);
    if (NULL == pcresponsebuf)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_MALLOC_ERR;
    }
    MEMSET(pcresponsebuf,0,ulresponsebuflen);
    
    slret = hilink_send_request(HILINK_REQUEST_GETAUTOMODE,ulresponsebuflen,pcresponsebuf,NULL);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_check(pcresponsebuf);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    #if 0
    slret = hilink_response_getvalue("<RoamAutoConnectEnable>",pcresponsebuf, &(pstrautomodeinfo->ulroamautoconable));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getvalue("<AutoReconnect>",pcresponsebuf, &(pstrautomodeinfo->ulautoreconnect));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getvalue("<RoamAutoReconnectEnable>",pcresponsebuf, &(pstrautomodeinfo->ulroamautoreconable));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getvalue("<ReconnectInterval>",pcresponsebuf, &(pstrautomodeinfo->ulreconnectinterval));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getvalue("<MaxIdelTime>",pcresponsebuf, &(pstrautomodeinfo->ulmaxidletime));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getvalue("<ConnectMode>",pcresponsebuf, &(pstrautomodeinfo->ulautomode));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
        
    slret = hilink_response_getvalue("<MTU>",pcresponsebuf, &(pstrautomodeinfo->ulmtu));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    #endif

    slret = hilink_response_getvalue("<ConnectMode>",pcresponsebuf, &(pstrautomodeinfo->ulautomode));
    if (HILINK_OK != slret)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
    }
    
    //HILINK_PRINT("<ConnectMode>:%d.\r\n",pstrautomodeinfo->ulautomode);
    (void)hilink_get_automodetempleatestatus(&ulautomodestatus);
    if (HILINK_BUFSTATUS_NOINIT == ulautomodestatus)
    {        
        slret = hilink_form_setautomodetemplate(pcresponsebuf);
        if (HILINK_OK != slret)
        {
            (void)hilink_set_automodetempleatestatus(HILINK_BUFSTATUS_NOINIT);  
            HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        }
        else
        {
            (void)hilink_set_automodetempleatestatus(HILINK_BUFSTATUS_IDLE);
        }
    }

    free(pcresponsebuf);
    return HILINK_OK;
}

int hilink_getconnectstate_fromserver(HILINK_CONNECTSTATE_INFO_STRU *pstrconnectstateinfo)
{
    int slret = 0;
    unsigned int ulsimcardstate = 0;
    unsigned int ulresponsebuflen = 0;
    char *pcresponsebuf = NULL;

    if (NULL == pstrconnectstateinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    ulresponsebuflen = HILINK_RESPONSE_BUFLEN;
    pcresponsebuf = (char *)malloc(ulresponsebuflen);
    if (NULL == pcresponsebuf)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_MALLOC_ERR;
    }
    MEMSET(pcresponsebuf,0,ulresponsebuflen);

    slret = hilink_send_request(HILINK_REQUEST_GETCONNECTSTATE,ulresponsebuflen,pcresponsebuf,NULL);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_check(pcresponsebuf);
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_response_getvalue("<ConnectionStatus>",pcresponsebuf, &(pstrconnectstateinfo->ulconnectstate));
    if (HILINK_OK != slret)
    {
        free(pcresponsebuf);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    if ((pstrconnectstateinfo->ulconnectstate < HILINK_GETSTATE_CONNECTING)||(pstrconnectstateinfo->ulconnectstate >= HILINK_GETSTATE_MAX))
    {
        HILINK_PRINT("%s:%d:%d unknown state.\r\n",__FUNCTION__,__LINE__,pstrconnectstateinfo->ulconnectstate);
        pstrconnectstateinfo->ulconnectstate = HILINK_GETSTATE_DISCONNECT;
    }

    slret = hilink_response_getvalue("<SimStatus>",pcresponsebuf,&ulsimcardstate);
    if ((HILINK_OK != slret)&&(HILINK_NOFINDVALUE_ERR != slret))
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
    }
    if (0xff == ulsimcardstate)
    {
        pstrconnectstateinfo->ulsimcardstate = HILINK_SIMCARD_OFFLINE;
    }
    else
    {
        pstrconnectstateinfo->ulsimcardstate = HILINK_SIMCARD_ONLINE;
    }

    //HILINK_PRINT("<ConnectionStatus>:%d,<SimStatus>:0x%x.\r\n",pstrconnectstateinfo->ulconnectstate,ulsimcardstate);
    free(pcresponsebuf);
    return HILINK_OK;
}

int hilink_plug_setflag(unsigned int ulflag)
{
    if (HILINK_EVENT_MAX <= ulflag)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }
    
    g_ulhilinkplugflag = ulflag;
    return HILINK_OK;
}

int hilink_plug_getflag(unsigned int *pulflag)
{
    if (NULL == pulflag)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }
    
    *pulflag = g_ulhilinkplugflag;
    return HILINK_OK;
}

int hilink_create_inforesource(void)
{    
    HILINK_INFO_STRU *pstrhilinkinfo = NULL;

    pstrhilinkinfo = (HILINK_INFO_STRU *)malloc(sizeof(HILINK_INFO_STRU));
    if (NULL == pstrhilinkinfo)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_MALLOC_ERR;
    }
    MEMSET(pstrhilinkinfo,0,sizeof(HILINK_INFO_STRU));
    (void)hilink_set_infopointer(pstrhilinkinfo);

    pstrhilinkinfo->mutex_connectstateinfo = osal_mutex_create();
    if (INVALID_ID == pstrhilinkinfo->mutex_connectstateinfo)
    {
        free(pstrhilinkinfo);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_MALLOC_ERR;
    }

    pstrhilinkinfo->ulsetautomodebuflen = HILINK_SETAUTOMODE_BUFLEN;
    pstrhilinkinfo->pcsetautomodebuf = (char *)malloc(pstrhilinkinfo->ulsetautomodebuflen);
    if (NULL == pstrhilinkinfo->pcsetautomodebuf)
    {
        OS_DeleteMutex(pstrhilinkinfo->mutex_connectstateinfo);
        free(pstrhilinkinfo);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_MALLOC_ERR;
    }
    MEMSET(pstrhilinkinfo->pcsetautomodebuf,0,pstrhilinkinfo->ulsetautomodebuflen);
    (void)hilink_set_automodetempleatestatus(HILINK_BUFSTATUS_NOINIT);

    pstrhilinkinfo->ulsetprofilebuflen = HILINK_SETPROFILE_BUFLEN;
    pstrhilinkinfo->pcsetprofilebuf = (char *)malloc(pstrhilinkinfo->ulsetprofilebuflen);
    if (NULL == pstrhilinkinfo->pcsetprofilebuf)
    {
        OS_DeleteMutex(pstrhilinkinfo->mutex_connectstateinfo);
        free(pstrhilinkinfo->pcsetautomodebuf);
        free(pstrhilinkinfo);
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_MALLOC_ERR;
    }
    MEMSET(pstrhilinkinfo->pcsetprofilebuf,0,pstrhilinkinfo->ulsetprofilebuflen);
    (void)hilink_set_profiletempleatestatus(HILINK_BUFSTATUS_NOINIT);

    return HILINK_OK;
}

int hilink_destroy_inforesource(void)
{
    unsigned int ulautomodestatus = 0;
    unsigned int ulprofilestatus = 0;
    HILINK_INFO_STRU *pstrhilinkinfo = NULL;

    (void)hilink_get_infopointer(&pstrhilinkinfo);
    if (NULL == pstrhilinkinfo)
    {
        return HILINK_OK;
    }

    (void)hilink_get_profiletempleatestatus(&ulprofilestatus);
    (void)hilink_get_automodetempleatestatus(&ulautomodestatus);
    while ((HILINK_BUFSTATUS_BUSY == ulprofilestatus)||(HILINK_BUFSTATUS_BUSY == ulautomodestatus))
    {
        osal_task_sleep(50); 
        (void)hilink_get_profiletempleatestatus(&ulprofilestatus);
        (void)hilink_get_automodetempleatestatus(&ulautomodestatus);
    }

    (void)hilink_set_profiletempleatestatus(HILINK_BUFSTATUS_FREE);
    (void)hilink_set_automodetempleatestatus(HILINK_BUFSTATUS_FREE);
    if (INVALID_ID != pstrhilinkinfo->mutex_connectstateinfo)
    {
        OS_DeleteMutex(pstrhilinkinfo->mutex_connectstateinfo);
    }

    free(pstrhilinkinfo->pcsetautomodebuf);
    free(pstrhilinkinfo->pcsetprofilebuf);
    free(pstrhilinkinfo);
    (void)hilink_set_infopointer(NULL);
    return HILINK_OK;
}

int hilink_attach_netif()
{
    int slret = 0;
    struct net_device *pstrnetdevice = NULL;
    struct netif *pstrcurnetif = NULL;

    pstrnetdevice = dev_get_by_type(NULL, HLD_DEV_TYPE_USBNET);
    if (NULL == pstrnetdevice)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }

    if(pstrnetdevice->flags & HLD_DEV_STATS_ATTACHED)
    {
        return HILINK_OK;
    }

    pstrcurnetif = sys_add_netif2(pstrnetdevice,IP_ADDR_ANY, IP_ADDR_ANY, IP_ADDR_ANY);
	if (NULL == pstrcurnetif)
	{
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
	}

    libnet_dhcp_on2(pstrcurnetif);
    pstrnetdevice->flags |= HLD_DEV_STATS_ATTACHED;

    return HILINK_OK;
}

int hilink_detach_netif()
{
    int slret = 0;
    struct net_device *pstrnetdevice = NULL;
    struct netif *pstrcurnetif = NULL;

    pstrnetdevice = dev_get_by_type(NULL, HLD_DEV_TYPE_USBNET);
    if (NULL == pstrnetdevice)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_PARA_ERR;
    }
    
    if((pstrnetdevice->flags & HLD_DEV_STATS_ATTACHED) != HLD_DEV_STATS_ATTACHED)
    {
        return HILINK_OK;
    }
	
	net_close(pstrnetdevice);
    sys_del_netif(pstrnetdevice);
        
	return 0;
}

int hilink_check_dhcpstate()
{
    unsigned int ultimeout = 0;
    unsigned int ultimecnt = 0;
    struct netif *pstrnetif = NULL;

    #if 0
    pstrnetif = netif_find("en0");
	if (pstrnetif == NULL)
	{
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;        
	}
    #endif

    pstrnetif = netif_find_by_type(HLD_DEV_TYPE_USBNET);
	if (pstrnetif == NULL)
	{
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;        
	}

    ultimeout = 60 * 1000;
    while (ultimecnt < ultimeout)
    {
        if ((!ip_addr_cmp(&(pstrnetif->ip_addr), IP_ADDR_ANY))
			&& (!ip_addr_cmp(&(pstrnetif->netmask), IP_ADDR_ANY))
			&& (!ip_addr_cmp(&(pstrnetif->gw), IP_ADDR_ANY)))
        {
            HILINK_PRINT("hilink dhcp ok.\r\n");
            break;
        }

        osal_task_sleep(200);
        ultimecnt += 200;
    }

    if (ultimecnt >= ultimeout)
    {
        HILINK_PRINT("hilink dhcp fail.\r\n");
        return HILINK_DHCP_ERR; 
    }

    return HILINK_OK;
}

int hilink_task_maintain()
{
    unsigned int ulflag = 0;
    unsigned int ulplugflag = 0;
    unsigned int ulstatechange = 0;
    unsigned int uluseflag = 0;
    HILINK_PROFILE_INFO_STRU strprofileinfo = {0};
    HILINK_AUTOMODE_INFO_STRU strautomodeinfo = {0};
    HILINK_CONNECTSTATE_INFO_STRU strconnectstateinfo = {0};
    HILINK_CONNECTSTATE_INFO_STRU strconnectstateinfoold = {0};
    HILINK_SETCONNECT_STATE_STRU strsetconnectstate = {0};

    (void)hilink_plug_getflag(&ulplugflag);
    (void)hilink_get_useflag(&uluseflag);
    if ((HILINK_EVENT_PLUGOUT == ulplugflag)||(HILINK_USEFLAG_USE != uluseflag))
    {
        return HILINK_OK;
    }
    (void)hilink_getconnectstate_fromserver(&strconnectstateinfo);
    (void)hilink_setconnectstate_tolocall(strconnectstateinfo);

    #if 0 
    (void)hilink_plug_getflag(&ulplugflag);
    (void)hilink_get_useflag(&uluseflag);
    if ((HILINK_EVENT_PLUGOUT == ulplugflag)||(HILINK_USEFLAG_USE != uluseflag))
    {
        return HILINK_OK;
    }
    (void)hilink_getautomodeinfo_fromserver(&strautomodeinfo);
    (void)hilink_setautomodeinfo_tolocall(strautomodeinfo);
  
    (void)hilink_plug_getflag(&ulplugflag);
    (void)hilink_get_useflag(&uluseflag);
    if ((HILINK_EVENT_PLUGOUT == ulplugflag)||(HILINK_USEFLAG_USE != uluseflag))
    {
        return HILINK_OK;
    }
    (void)hilink_getprofileinfo_fromserver(&strprofileinfo);
    (void)hilink_setprofileinfo_tolocall(strprofileinfo);
    #endif  
    
    while (1)
    {
        (void)hilink_plug_getflag(&ulplugflag);
        (void)hilink_get_useflag(&uluseflag);
        if ((HILINK_EVENT_PLUGOUT == ulplugflag)||(HILINK_USEFLAG_USE != uluseflag))
        {
            break;         
        }
        
        (void)hilink_getconnectstate_fromserver(&strconnectstateinfo);
        (void)hilink_getconnectstate_fromlocall(&strconnectstateinfoold);
        (void)hilink_setconnectstate_tolocall(strconnectstateinfo);
        if (HILINK_SIMCARD_OFFLINE == strconnectstateinfo.ulsimcardstate)
        {
            if (HILINK_SIMCARD_OFFLINE != strconnectstateinfoold.ulsimcardstate)
            {
                ulstatechange = HILINK_STATECHANGE_NOCARD;
                (void)hilink_sendmessage_statechange(ulstatechange);
            }
            osal_task_sleep(HILINK_SLEEP_TIME);
            continue;
        }

        if ((HILINK_SIMCARD_OFFLINE == strconnectstateinfoold.ulsimcardstate)\
            ||(strconnectstateinfo.ulconnectstate != strconnectstateinfoold.ulconnectstate))
        {
            ulstatechange = strconnectstateinfo.ulconnectstate - HILINK_GETSTATE_CONNECTING + 1;
            (void)hilink_sendmessage_statechange(ulstatechange);
        }

        (void)hilink_plug_getflag(&ulplugflag);
        (void)hilink_get_useflag(&uluseflag);
        if ((HILINK_EVENT_PLUGOUT == ulplugflag)||(HILINK_USEFLAG_USE != uluseflag))
        {
            break;
        }
        (void)hilink_getautomodeinfo_fromserver(&strautomodeinfo);
        (void)hilink_setautomodeinfo_tolocall(strautomodeinfo);
        if (HILINK_AUTOMODE_ENABLE == strautomodeinfo.ulautomode)
        {
            if ((HILINK_GETSTATE_CONNECTING != strconnectstateinfo.ulconnectstate)\
                ||(HILINK_GETSTATE_CONNECT != strconnectstateinfo.ulconnectstate))
            {
                if (1 == ulflag)
                {
                    strsetconnectstate.ulsetconnectstate = HILINK_CONNECTSTATE_SETCONNECT;
                    (void)hilink_setconnectstate_toserver(strsetconnectstate);
                    ulflag = 0;
                }
                else
                {
                    ulflag = 1;
                }
            }
            else
            {
                ulflag = 0;
            }
        }
        
        osal_task_sleep(HILINK_SLEEP_TIME);
    }

    return HILINK_OK;
}

int hilink_exit()
{
    int slret =0;
    
    slret = hilink_detach_netif();
    if (HILINK_OK != slret)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
    }

    #if 0
    slret = ethernet_open();
    if (HILINK_OK != slret)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
    }
    #endif

    (void)hilink_set_initflag(0);
    return HILINK_OK;
}

int hilink_init()
{
    int slret =0;
    //unsigned int ulstatechange = 0;
    HILINK_AUTOMODE_INFO_STRU strautomodeinfo = {0};

    slret = hilink_attach_netif();
    if (HILINK_OK != slret)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    slret = hilink_create_inforesource();
    if (HILINK_OK != slret)
    {
        (void)hilink_detach_netif();
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return;
    }

    slret = hilink_check_dhcpstate();
    if (HILINK_OK != slret)
    {
        (void)hilink_destroy_inforesource();
        (void)hilink_detach_netif();
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

    (void)hilink_getautomodeinfo_fromserver(&strautomodeinfo);
    (void)hilink_setautomodeinfo_tolocall(strautomodeinfo);
    //ulstatechange = HILINK_STATECHANGE_INITOK;
    //(void)hilink_sendmessage_statechange(ulstatechange);
    (void)hilink_set_initflag(1);
    return HILINK_OK;
}

void hilink_task(unsigned int ulpara1,unsigned int ulpara2)
{
    int slret =0; 
    unsigned int ulinitflag = 0;
    unsigned int ulplugflag = 0;

    #if 0
    slret = hilink_init();
    if (HILINK_OK != slret)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }
    #endif

    HILINK_TASK_LOOP:
    while (1)
    {
        (void)hilink_plug_getflag(&ulplugflag);
        if (HILINK_EVENT_PLUGOUT == ulplugflag)
        {
            (void)hilink_get_initflag(&ulinitflag);
            if (ulinitflag)
            {
                hilink_exit();
            }
            return HILINK_OK;
        }

        (void)hilink_get_initflag(&ulinitflag);
        if (0 == ulinitflag)
        {
            osal_task_sleep(200);
        }
        else
        {
            break;
        }
    }

    #if 0
    slret = hilink_create_inforesource();
    if (HILINK_OK != slret)
    {
        (void)hilink_exit();
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return;
    }
    #endif

    (void)hilink_task_maintain();

    (void)hilink_destroy_inforesource();
    (void)hilink_exit();
    (void)hilink_plug_getflag(&ulplugflag);
    if (HILINK_EVENT_PLUGOUT != ulplugflag)
    {
        goto HILINK_TASK_LOOP;
    }

    //HILINK_PRINT("%s:leave task...\r\n",__FUNCTION__,__LINE__);
    return;
}

int hilink_creat_task(unsigned int ulpara1,unsigned int ulpara2)
{
	OSAL_T_CTSK t_ctsk;
	OSAL_ID tsk_id;

	t_ctsk.itskpri = OSAL_PRI_NORMAL;
	t_ctsk.stksz = 0x8000;
	t_ctsk.quantum = 10;
	t_ctsk.para1 = ulpara1;
	t_ctsk.para2 = 0;
	t_ctsk.name[0] = 'H';
	t_ctsk.name[1] = 'I';
	t_ctsk.name[2] = 'L';
	t_ctsk.task = (TP)hilink_task;
	tsk_id = osal_task_create(&t_ctsk);
    if (OSAL_INVALID_ID == tsk_id)
    {
        HILINK_PRINT("%s:%d:error.\r\n",__FUNCTION__,__LINE__);
        return HILINK_CALL_ERR;
    }

	return HILINK_OK;
}
#endif

